<template>
    <div>
        <div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="点击上传头像"
                                                                class="img-circle img-lg"/></div>
        <el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened"
                   @close="closeDialog">
            <el-row>
                <el-col :xs="24" :md="12" :style="{height: '350px'}">
                    <vue-cropper
                        ref="cropperRef"
                        :img="options.img"
                        :info="true"
                        :autoCrop="options.autoCrop"
                        :autoCropWidth="options.autoCropWidth"
                        :autoCropHeight="options.autoCropHeight"
                        :fixedBox="options.fixedBox"
                        :outputType="options.outputType"
                        @realTime="realTime"
                        v-if="visible"
                    />
                </el-col>
                <el-col :xs="24" :md="12" :style="{height: '350px'}">
                    <div class="avatar-upload-preview">
                        <img :src="previews.url" :style="previews.img"/>
                    </div>
                </el-col>
            </el-row>
            <br/>
            <el-row>
                <el-col :lg="2" :sm="3" :xs="3">
                    <el-upload action="#" :http-request="requestUpload" :show-file-list="false"
                               :before-upload="beforeUpload">
                        <el-button>
                            选择
                            <i class="el-icon-upload el-icon--right"></i>
                        </el-button>
                    </el-upload>
                </el-col>
                <el-col :lg="{span: 1, offset: 2}" :sm="2" :xs="2">
                    <el-button @click="changeScale(1)">
                        <template #icon>
                            <el-icon-plus/>
                        </template>
                    </el-button>
                </el-col>
                <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
                    <el-button @click="changeScale(-1)">
                        <template #icon>
                            <el-icon-minus/>
                        </template>
                    </el-button>
                </el-col>
                <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
                    <el-button @click="rotateLeft()">
                        <template #icon>
                            <el-icon-refresh-left/>
                        </template>
                    </el-button>
                </el-col>
                <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2">
                    <el-button @click="rotateRight()">
                        <template #icon>
                            <el-icon-refresh-right/>
                        </template>
                    </el-button>
                </el-col>
                <el-col :lg="{span: 2, offset: 6}" :sm="2" :xs="2">
                    <el-button type="primary" @click="uploadImg()">提 交</el-button>
                </el-col>
            </el-row>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup>
import {VueCropper} from "vue-cropper";
import 'vue-cropper/dist/index.css'
import {uploadAvatar} from "@/api/system/user";
import {debounce} from '@/utils'
import {useUserStoreHook} from "@/store/modules/user";

const useUserStore = useUserStoreHook()
const cropperRef = ref()
// 是否显示弹出层
const open = ref(false)
// 是否显示cropper
const visible = ref(false)
// 弹出层标题
const title = ref("修改头像")
const options = ref<any>({
    img: useUserStore.user.avatar, //裁剪图片的地址
    autoCrop: true, // 是否默认生成截图框
    autoCropWidth: 200, // 默认生成截图框宽度
    autoCropHeight: 200, // 默认生成截图框高度
    fixedBox: true, // 固定截图框大小 不允许改变
    outputType: "png", // 默认生成截图为PNG格式
    filename: ''
})
const previews = ref({})
const resizeHandler = ref<any>(null)

// 编辑头像
function editCropper() {
    open.value = true;
}

// 打开弹出层结束时的回调
function modalOpened() {
    visible.value = true;
    if (!resizeHandler.value) {
        resizeHandler.value = debounce(() => {
            refresh()
        }, 100, true)
    }
    window.addEventListener("resize", resizeHandler.value)
}

// 刷新组件
function refresh() {
    cropperRef.value.refresh();
}

// 覆盖默认的上传行为
function requestUpload() {
}

// 向左旋转
function rotateLeft() {
    cropperRef.value.rotateLeft();
}

// 向右旋转
function rotateRight() {
    cropperRef.value.rotateRight();
}

// 图片缩放
function changeScale(num) {
    num = num || 1;
    cropperRef.value.changeScale(num);
}

// 上传预处理
function beforeUpload(file) {
    if (file.type.indexOf("image/") == -1) {
        ElMessage.error("文件格式错误，请上传图片类型,如：JPG，PNG后缀的文件。");
    } else {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => {
            options.value.img = reader.result;
            options.value.filename = file.name;
        };
    }
}

// 上传图片
function uploadImg() {
    cropperRef.value.getCropBlob(data => {
        let formData = new FormData();
        formData.append("avatarfile", data, options.value.filename);
        uploadAvatar(formData).then(response => {
            open.value = false;
            options.value.img = response.data.imgUrl;
            store.commit('SET_AVATAR', options.value.img);
            ElMessage.success("修改成功");
            visible.value = false;
        });
    });
}

// 实时预览
function realTime(data) {
    previews.value = data;
}

// 关闭窗口
function closeDialog() {
    options.value.img = useUserStore.user
    visible.value = false;
    open.value = false
    window.removeEventListener("resize", resizeHandler.value)
}
</script>
<style scoped lang="scss">
.user-info-head {
    position: relative;
    display: inline-block;
    height: 120px;
}

.user-info-head:hover:after {
    content: '+';
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    color: #eee;
    background: rgba(0, 0, 0, 0.5);
    font-size: 24px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    cursor: pointer;
    line-height: 110px;
    border-radius: 50%;
}
</style>

